/*

 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.codecarpet.fbconnect;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.util.Log;

import com.codecarpet.fbconnect.FBRequest.FBRequestDelegate;

public class FBLoginDialog extends FBDialog {

	private static final String LOG = FBLoginDialog.class.getSimpleName();

	private static final String LOGIN_URL = "http://www.facebook.com/login.php";

	private FBRequest mGetSessionRequest;
	private FBRequestDelegate mRequestDelegate;

	public FBLoginDialog(Activity context, FBSession session) {
		super(context, session);
		mRequestDelegate = new FBRequestDelegateImpl();
	}

	// /////////////////////////////////////////////////////////////////////////////////////////////////
	// private

	private void connectToGetSession(String token) {
		mGetSessionRequest = FBRequest.requestWithSession(mSession,
				mRequestDelegate);
		Map<String, String> params = new HashMap<String, String>();
		params.put("auth_token", token);
		if (mSession.getApiSecret() != null) {
			params.put("generate_session_secret", "1");
		}

		if (mSession.getGetSessionProxy() != null) {
			mGetSessionRequest.post(mSession.getGetSessionProxy(), params);
		} else {
			mGetSessionRequest.call("facebook.auth.getSession", params);
		}
	}

	private void loadLoginPage() {
		Map<String, String> params = new HashMap<String, String>();
		params.put("fbconnect", "1");
		params.put("connect_display", "touch");
		params.put("api_key", mSession.getApiKey());
		params.put("next", "fbconnect://success");

		try {
			loadURL(LOGIN_URL, "GET", params, null);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// /////////////////////////////////////////////////////////////////////////////////////////////////
	// FBDialog

	@Override
	protected void load() {
		loadLoginPage();
	}

	@Override
	protected void dialogWillDisappear() {
		// _webView.stringByEvaluatingJavaScriptFromString("email.blur();");
		if (mGetSessionRequest == null) {
			Log.w(LOG,
					"This should not be null, at least on iPhone it is not...");
		} else {
			mGetSessionRequest.cancel();
		}
	}

	@Override
	protected void dialogDidSucceed(URI url) {
		String q = url.getQuery();
		int start = q.indexOf("auth_token=");
		if (start != -1) {
			int end = q.indexOf("&");
			int offset = start + "auth_token=".length();
			String token = end == -1 ? q.substring(offset) : q.substring(
					offset, end - offset);

			if (token != null) {
				connectToGetSession(token);
				Map<String, String> params = new HashMap<String, String>();
				System.out.println("Session key:" + mSession.getSessionKey());
				System.out.println("Token: " + token);
				params.clear();
				params.put("client_id", mSession.getApiKey());
				params.put("client_secret", mSession.getApiSecret());
				params.put("type", "client_cred");
				params.put("sessions", mSession.getSessionKey());
				String accessToken = null;
				try {
					accessToken = postURL(
							"https://graph.facebook.com/oauth/exchange_sessions",
							params, false);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				try {
					JSONArray jsonArr = new JSONArray(accessToken);
					JSONObject jsonObj = jsonArr.getJSONObject(0);
					String authtoken = (String)jsonObj.get("access_token");
					mSession.setAccessToken(authtoken);
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(mSession.getAccessToken() + " ");
			}
		}
		// super.dialogDidSucceed(url);
	}

	private class FBRequestDelegateImpl extends FBRequestDelegate {

		@Override
		public void requestDidLoad(FBRequest request, Object result) {

			try {
				JSONObject jsonObject = (JSONObject) result;
				Long uid = jsonObject.getLong("uid"); // XXX maybe create Long?
				String sessionKey = jsonObject.getString("session_key");
				String sessionSecret = jsonObject.getString("secret");
				Long expires = jsonObject.getLong("expires");
				Date expiration = null;
				if (expires != null) {
					expiration = new Date(expires);
				}

				mGetSessionRequest = null;

				mSession.begin(mContext, uid, sessionKey, sessionSecret,
						expiration);
				mSession.resume(mContext);

				dismissWithSuccess(true, true);
			} catch (JSONException e) {
				e.printStackTrace();
			}

		}

		@Override
		public void requestDidFailWithError(FBRequest request, Throwable error) {
			mGetSessionRequest = null;

			dismissWithError(error, true);
		}

	}

}